package com.dc.dbus.transport.commons;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;

public class NetUtil {
	
	protected final static Comparator<String> sortIpList_internalIpFirst = new Comparator<String>() {
		@Override
		public int compare(String o1, String o2) {
			
			boolean isInternalIp_1 = internalIp(o1);
			boolean isInternalIp_2 = internalIp(o2);
			
			if (isInternalIp_1) {
				if (!isInternalIp_2) {
					return -1;
				}
			} else {
				if (isInternalIp_2) {
					return 1;
				}
			}
			
			return 0;
		}
	};
	
	public static List<String> sortIpList_internalIpFirst(List<String> ipList) {
		
		Collections.sort(ipList, sortIpList_internalIpFirst);
		return ipList;
	}
	
	public static List<String> getLocalIPList() {
        List<String> ipList = new ArrayList<String>();
        try {
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            NetworkInterface networkInterface;
            Enumeration<InetAddress> inetAddresses;
            InetAddress inetAddress;
            String ip;
            while (networkInterfaces.hasMoreElements()) {
                networkInterface = networkInterfaces.nextElement();
                inetAddresses = networkInterface.getInetAddresses();
                while (inetAddresses.hasMoreElements()) {
                    inetAddress = inetAddresses.nextElement();
                    if (inetAddress instanceof Inet4Address
                    		&& !inetAddress.isLoopbackAddress()) { // IPV4
                        ip = inetAddress.getHostAddress();
                        ipList.add(ip);
                    }
                }
            }
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
        return ipList;
    }
	
	@SuppressWarnings("restriction")
	public static boolean internalIp(String ip) {
		
	    byte[] addr = sun.net.util.IPAddressUtil.textToNumericFormatV4(ip);
	    return internalIp(addr);
	}

	public static boolean internalIp(byte[] addr) {
	    final byte b0 = addr[0];
	    final byte b1 = addr[1];
	    //10.x.x.x/8
	    final byte SECTION_1 = 0x0A;
	    //172.16.x.x/12
	    final byte SECTION_2 = (byte) 0xAC;
	    final byte SECTION_3 = (byte) 0x10;
	    final byte SECTION_4 = (byte) 0x1F;
	    //192.168.x.x/16
	    final byte SECTION_5 = (byte) 0xC0;
	    final byte SECTION_6 = (byte) 0xA8;
	    switch (b0) {
	        case SECTION_1:
	            return true;
	        case SECTION_2:
	            if (b1 >= SECTION_3 && b1 <= SECTION_4) {
	                return true;
	            }
	        case SECTION_5:
	            switch (b1) {
	                case SECTION_6:
	                    return true;
	            }
	        default:
	            return false;

	    }
	}
	
}
